package pl.kosmowska.ewelina.client.app.activity;


import gwtupload.client.IUploadStatus;
import gwtupload.client.IUploader;
import gwtupload.client.IUploader.OnFinishUploaderHandler;
import gwtupload.client.IUploader.OnStartUploaderHandler;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import pl.kosmowska.ewelina.client.Constants;
import pl.kosmowska.ewelina.client.app.ClientFactory;
import pl.kosmowska.ewelina.client.app.activity.places.BankStatementImportPlace;
import pl.kosmowska.ewelina.client.app.activity.places.SignInPlace;
import pl.kosmowska.ewelina.client.app.requestfactory.OutcomeDataRequest;
import pl.kosmowska.ewelina.client.app.requestfactory.dto.OutcomeDataProxy;
import pl.kosmowska.ewelina.client.app.user.AuthEvent;
import pl.kosmowska.ewelina.client.app.user.AuthEvent.Auth;
import pl.kosmowska.ewelina.client.app.user.AuthEventHandler;
import pl.kosmowska.ewelina.client.views.BankStatementImportView;

import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.place.shared.Place;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.xml.client.Document;
import com.google.gwt.xml.client.XMLParser;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.google.web.bindery.requestfactory.shared.ServerFailure;

public class BankStatementImportActivity extends AbstractActivity implements BankStatementImportView.Presenter {

	private BankStatementImportView view;

	private ClientFactory clientFactory;

	public BankStatementImportActivity(BankStatementImportPlace place, ClientFactory clientFactory) {
		this.clientFactory = clientFactory;
	}


	@Override
	public void start(AcceptsOneWidget containerWidget, EventBus eventBus) {
		view = clientFactory.getBankStatementImportView();
		view.setPresenter(this);
		initAuthorisationForView();
		initUploader();
		startView();
		containerWidget.setWidget(view.asWidget());

	}
	
	private void initAuthorisationForView() {
		if (view.isAlreadyInit() == false) {
			clientFactory.getEventBus().addHandler(AuthEvent.TYPE, new AuthEventHandler() {
				public void onAuthEvent(AuthEvent event) {
					Auth e = event.getAuthEvent();
					if (e == Auth.LOGGEDIN) {
						view.reInitView();
					} else if (e == Auth.LOGGEDOUT) {
						goToSignInPlace();
					}
				}
			});
		}
		view.setAlreadyInit(true);
	}

	private void initUploader() {
		view.getUploader().setServletPath("uploader.uploadServlet");
		view.setFinishUploadHandler(initFinishUploadHandler());
		view.setStartUploadHandler(initStartUploadHandler());
		
	}
	
	private void startView() {
		if (clientFactory.getIsLoggedIn() == null) {
			// wait for login event b/c hasn't happened yet
		} else if (clientFactory.getIsLoggedIn() == true) {
			view.reInitView();
		} else if (clientFactory.getIsLoggedIn() == false) { 
			goToSignInPlace();
		}
	}

	private OnStartUploaderHandler initStartUploadHandler() {

		OnStartUploaderHandler uploadStartHandler = new IUploader.OnStartUploaderHandler() {
			@Override
			public void onStart(IUploader uploader) {
				clientFactory.getAppLoadingView().startProcessing();
				//view.showLoading(true);
				
			}
		};
		return uploadStartHandler;
	}

	private OnFinishUploaderHandler initFinishUploadHandler() {	
		OnFinishUploaderHandler uploadFinishHandler = new IUploader.OnFinishUploaderHandler() {
			@Override
			public void onFinish(IUploader uploader) {
				if (uploader.getStatus() == IUploadStatus.Status.SUCCESS) {
					String response = uploader.getServerResponse();
					if (response != null) {
						Document doc = XMLParser.parse(response);
						String servletResponse = IUploader.Utils.getXmlNodeValue(doc, "message");
						if(servletResponse!=null){
							OutcomeDataRequest req = clientFactory.getRequestFactory().getOutcomeDataRequest();
							List<OutcomeDataProxy> outcomeList = getOutcomeList(servletResponse,req);
							if(outcomeList.size()>0){
								saveOutcomes(outcomeList,req);
							}
						}
					} else {
						clientFactory.getAppLoadingView().stopProcessing();
						view.showMessage("Import nie powiódł się. Spróbuj ponownie.");
					}

				} else {
					clientFactory.getAppLoadingView().stopProcessing();
					view.showMessage("Import nie powiódł się. Spróbuj ponownie.");
				}
			}
		};
		return uploadFinishHandler;
	}
	private void saveOutcomes(List<OutcomeDataProxy> outcomeList, OutcomeDataRequest req) {
		req.persistAll(outcomeList).fire(new Receiver<List<OutcomeDataProxy>>() {
			public void onSuccess(List<OutcomeDataProxy> returnedOutcomeData) {
				clientFactory.getAppLoadingView().stopProcessing();
			//	view.showLoading(false);
				view.showMessage("Import danych zakończony sukcesem.");
			}
			public void onFailure(ServerFailure error) {
				view.showMessage("B\u0142\u0105d zapisu. Spr\u00F3buj ponownie!");
				clientFactory.getAppLoadingView().stopProcessing();
				super.onFailure(error);
			}
		});
		
	}

	private List<OutcomeDataProxy> getOutcomeList(String servletResponse,OutcomeDataRequest req) {
		List<OutcomeDataProxy> outcomeList = new ArrayList<OutcomeDataProxy>();
		String outcomes [] = servletResponse.split("#");
		for (int i=0; i< outcomes.length; i++){
			String outcomeData [] = outcomes[i].split("\\|");
			if(outcomeData.length!=3)
				continue;
			else{
				OutcomeDataProxy outcomeDataProxy = getOutcomeData(req, outcomeData);
				if(outcomeDataProxy!=null){
					outcomeList.add(outcomeDataProxy);
				}
			}
		}
		return outcomeList;

	}

	private OutcomeDataProxy getOutcomeData(OutcomeDataRequest req,
			String[] outcomeData) {
		OutcomeDataProxy newOutcome = req.create(OutcomeDataProxy.class);
		try{
			DateTimeFormat dateTimeFormat = DateTimeFormat.getFormat("yyyy-MM-dd");
			Date date = dateTimeFormat.parse(outcomeData[0]);
			newOutcome.setName(outcomeData[1]);
			newOutcome.setValue(Float.parseFloat(outcomeData[2]));
			newOutcome.setDate(date);
			newOutcome.setPriority("Wysoki");
			newOutcome.setCategory(Constants.IMPORT_CATEGORY);
			newOutcome.setMultiple(false);
			
		}catch(Exception e){
			return null;
		}
		return newOutcome;
	}





	public void goTo(Place place) {
		clientFactory.getPlaceController().goTo(place);
	}

	@Override
	public void goToSignInPlace() {
		clientFactory.getPlaceController().goTo(new SignInPlace());

	}



}


